home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 July: Mac OS SDK / Dev.CD Jul 00 SDK2.toast / Development Kits / Hardware / Mac OS USB DDK / Mac OS USB DDK 1.4.1 / Examples / DropPrint•USB / TestPrinterClass.c < prev    next >
Encoding:
Text File  |  2000-04-25  |  11.3 KB  |  364 lines  |  [TEXT/CWIE]

  1. // File TestPrinterClass.c
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <types.h>
  7.  
  8. #include <gestalt.h>
  9. #include <errors.h>
  10.  
  11. #ifndef __DIALOGS__
  12. #include <Dialogs.h>
  13. #endif
  14. #ifndef __EVENTS__
  15. #include <Events.h>
  16. #endif
  17. #ifndef __FILES__
  18. #include <Files.h>
  19. #endif
  20. #ifndef __DEVICES__
  21. #include <Devices.h>
  22. #endif
  23. #include <textedit.h>
  24.  
  25. #ifndef __NUMBERFORMATTING__
  26. #include <numberformatting.h>
  27. #endif
  28.  
  29. #include "TestPrinterClass.h"
  30. #include "SafeNameRegistry.h"
  31.  
  32. #if UNIVERSAL_INTERFACES_VERSION < 0x0330
  33. enum {
  34.     kUSBNoErr                    = 0,
  35.     kUSBNoTran                    = 0,
  36.     kUSBNoDelay                    = 0,
  37.     kUSBPending                    = 1,                            /* */
  38.                                                                 /* USB assigned error numbers in range -6900 .. -6999 */
  39.     kUSBBaseError                = -7000,                        /* */
  40.                                                                 /* USB Services Errors */
  41.     kUSBInternalErr                = -6999,                        /* Internal error */
  42.     kUSBUnknownDeviceErr        = -6998,                        /*  device ref not recognised */
  43.     kUSBUnknownPipeErr            = -6997,                        /*  Pipe ref not recognised */
  44.     kUSBTooManyPipesErr            = -6996,                        /*  Too many pipes */
  45.     kUSBIncorrectTypeErr        = -6995,                        /*  Incorrect type */
  46.     kUSBRqErr                    = -6994,                        /*  Request error */
  47.     kUSBUnknownRequestErr        = -6993,                        /*  Unknown request */
  48.     kUSBTooManyTransactionsErr    = -6992,                        /*  Too many transactions */
  49.     kUSBAlreadyOpenErr            = -6991,                        /*  Already open */
  50.     kUSBNoDeviceErr                = -6990,                        /*  No device */
  51.     kUSBDeviceErr                = -6989,                        /*  Device error */
  52.     kUSBOutOfMemoryErr            = -6988,                        /*  Out of memory */
  53.     kUSBNotFound                = -6987,                        /*  Not found */
  54.     kUSBPBVersionError            = -6986,                        /*  Wrong pbVersion */
  55.     kUSBPBLengthError            = -6985,                        /*  pbLength too small */
  56.     kUSBCompletionError            = -6984,                        /*  no completion routine specified */
  57.     kUSBFlagsError                = -6983,                        /*  Flags not zeroed */
  58.     kUSBAbortedError            = -6982,                        /*  Pipe aborted */
  59.     kUSBNoBandwidthError        = -6981,                        /*  Not enough bandwidth available */
  60.     kUSBPipeIdleError            = -6980,                        /*  Pipe is Idle, it will not accept transactions */
  61.     kUSBPipeStalledError        = -6979,                        /*  Pipe has stalled, error needs to be cleared */
  62.     kUSBUnknownInterfaceErr        = -6978,                        /*  Interface ref not recognised */
  63.                                                                 /* */
  64.                                                                 /* USB Manager Errors */
  65.     kUSBBadDispatchTable        = -6950,                        /* Improper driver dispatch table */
  66.                                                                 /* */
  67.                                                                 /* Hardware Errors */
  68.                                                                 /* Note pipe stalls are communication */
  69.                                                                 /* errors. The affected pipe can not */
  70.                                                                 /* be used until USBClearPipeStallByReference  */
  71.                                                                 /* is used */
  72.                                                                 /* kUSBEndpointStallErr is returned in */
  73.                                                                 /* response to a stall handshake */
  74.                                                                 /* from a device. The device has to be */
  75.                                                                 /* cleared before a USBClearPipeStallByReference */
  76.                                                                 /* can be used */
  77.     kUSBLinkErr                    = -6916,
  78.     kUSBCRCErr                    = -6915,                        /*  Pipe stall, bad CRC */
  79.     kUSBBitstufErr                = -6914,                        /*  Pipe stall, bitstuffing */
  80.     kUSBDataToggleErr            = -6913,                        /*  Pipe stall, Bad data toggle */
  81.     kUSBEndpointStallErr        = -6912,                        /*  Device didn't understand */
  82.     kUSBNotRespondingErr        = -6911,                        /*  Pipe stall, No device, device hung */
  83.     kUSBPIDCheckErr                = -6910,                        /*  Pipe stall, PID CRC error */
  84.     kUSBWrongPIDErr                = -6909,                        /*  Pipe stall, Bad or wrong PID */
  85.     kUSBOverRunErr                = -6908,                        /*  Packet too large or more data than buffer */
  86.     kUSBUnderRunErr                = -6907,                        /*  Less data than buffer */
  87.     kUSBRes1Err                    = -6906,
  88.     kUSBRes2Err                    = -6905,
  89.     kUSBBufOvrRunErr            = -6904,                        /*  Host hardware failure on data in, PCI busy? */
  90.     kUSBBufUnderRunErr            = -6903,                        /*  Host hardware failure on data out, PCI busy? */
  91.     kUSBNotSent1Err                = -6902,                        /*  Transaction not sent */
  92.     kUSBNotSent2Err                = -6901                            /*  Transaction not sent */
  93. };
  94.  
  95. #endif
  96.  
  97. #define SECONDS( n )            (n*60)
  98. #define PROGRAM                "DropPrint•USB"
  99. #define kStrPrinterClass    PROGRAM ": "
  100.  
  101. enum {
  102.     kStatusDialog = 513
  103. };
  104.  
  105. enum {
  106.     kStatusBarItem = 1
  107. };
  108.  
  109.  
  110. char                *outbuffer = NULL;
  111. IOParam            fsendblk;
  112. unsigned long    fUSBReference;
  113. char                *filename;
  114. DialogPtr        gStatusDlg;
  115.  
  116. void        dump( char *p, long count );
  117. OSErr        sendfile( char *sourcefile, long buffersize );
  118. OSStatus OpenClassDriver( char *which_printer );
  119. void        showstatus( long current, long endfile );
  120.  
  121. void
  122. dump( char *p, long count )
  123. {
  124.     char    *q, *e, *f,
  125.             *d, line[64+32+1+1];    //2bytes per hex, 1 byte per char, 1 tab, 1 nul
  126.     short    nibble;
  127.  
  128.     while ( count > 0 )
  129.     {
  130.         q = p;                                    // start of line
  131.         e = p + 32;                                // proposed end of line
  132.         f = p + (count > 32? 32: count);    // actual end of line
  133.         d = line;
  134.         //
  135.         //    standard hex dump
  136.         //
  137.         for ( ; count > 0 && p < e; ++p, --count )
  138.         {
  139.             nibble = (*p >> 4) & 0x0F;
  140.             *d++ = nibble + (nibble > 9? 'A' - 10:'0');
  141.             nibble = *p & 0x0F;
  142.             *d++ = nibble + (nibble > 9? 'A' - 10:'0');
  143.         }
  144.         for ( ; p < e; ++p )
  145.         {
  146.             *d++ = ' ';
  147.             *d++ = ' ';
  148.         }
  149.         *d++ = '\t';
  150.         //
  151.         //    ascii sidebar
  152.         //
  153.         for ( p = q; p < f; ++p )
  154.             *d++ = *p < ' ' || *p >= 0x7F? '.': *p;
  155.         *d = '\0';
  156.         fprintf( stderr, "%s\n", line );
  157.     }
  158. }
  159.  
  160. OSStatus
  161. OpenClassDriver( char *which_printer )
  162. {
  163.     Str255            driverName;        // unit table driver name
  164.     OSStatus            err = -192;        // resNotFound
  165.     RegEntryID        self;
  166.     unsigned long    length;
  167.     
  168.     
  169.     fsendblk.ioRefNum = -1;                    // preload our IOParms in engvars
  170.     fsendblk.ioResult = 0;
  171.     fsendblk.ioCompletion = 0L;
  172.  
  173.     err = SafeRegistryEntryIDInit( &self );
  174.     if ( err == noErr )
  175.     {
  176.     
  177.         err = SafeRegistryCStrEntryLookup( nil, which_printer, &self );
  178.  
  179.         length = sizeof(driverName);
  180.         if ( err == noErr )
  181.             err = SafeRegistryPropertyGet( &self, "drvrOut", &driverName, &length );
  182.         if ( err == noErr )
  183.             err = OpenDriver( driverName, &fsendblk.ioRefNum );
  184.  
  185.         length = sizeof(fUSBReference);
  186.         if ( err == noErr )
  187.             err = SafeRegistryPropertyGet( &self, "privateData", &fUSBReference, &length );
  188.  
  189.         SafeRegistryEntryIDDispose(&self);
  190.     }
  191.  
  192.     return err;
  193. }
  194.  
  195. void
  196. showstatus( long current, long endfile )
  197. {
  198.     GrafPtr    oldport;
  199.     Rect        r;
  200.     Handle    h;
  201.     short        type;
  202.     long        width;
  203.     char        info[526];
  204.     
  205.     GetPort( &oldport );
  206.     SetPort( gStatusDlg );
  207.     GetDialogItem( gStatusDlg, kStatusBarItem, &type, &h, &r );
  208.     
  209.     // we have, width/ (r.right - r.left) == current/endfile
  210.     width = current *(r.right - r.left);
  211.     width /= endfile;
  212.     
  213.     FrameRect( &r );
  214.  
  215.     InsetRect( &r, 1, 1 );
  216.     sprintf( info, "%ld of %ld", current, endfile );
  217.     TETextBox( info, strlen(info), &r, teJustCenter );
  218.  
  219.     r.right = width + r.left;
  220.     InvertRect( &r );
  221.     
  222.     SetPort( oldport );
  223. }
  224.  
  225. OSErr
  226. sendfile( char *sourcefile, long buffersize )
  227. {
  228.     FILE                 *fin = fopen( sourcefile, "rb" );
  229.     long                count;
  230.     EventRecord        e;
  231.     OSStatus            err;
  232.     long                eoffin;    // length of input file
  233.     
  234.     gStatusDlg = GetNewDialog( kStatusDialog, nil, (WindowPtr)-1);
  235.  
  236.     if ( !fin )
  237.         err = fnfErr;        // cant open file
  238.     else
  239.     {
  240.         fseek( fin, 0, 2 /*fsFromEnd*/ );
  241.         eoffin = ftell( fin );
  242.         fseek( fin, 0, 0 /*fsFromStart*/ );
  243.         do {
  244.             count = fread( outbuffer, sizeof(char), buffersize, fin );
  245.             if ( count <= 0 )
  246.                 break;
  247.         //    dump( outbuffer, count );
  248.  
  249.             fsendblk.ioBuffer = outbuffer;
  250.             fsendblk.ioReqCount = count;
  251.             err = PBWriteAsync( (ParamBlockRec*) &fsendblk );
  252.             if ( err != noErr )
  253.                 break;
  254.             showstatus( ftell( fin ), eoffin );
  255.  
  256.             // wait for i/o to complete
  257.             while ( fsendblk.ioResult == 1 )
  258.             {
  259.                 WaitNextEvent( keyDownMask, &e, 0, NULL );
  260.                 if (e.what == keyDown && e.modifiers & cmdKey) {
  261.                     if ( (e.message & charCodeMask) == '.' )
  262.                         break;
  263.                 }
  264.             }
  265.             if ( fsendblk.ioResult != noErr )
  266.                 break;
  267.             // if user canceled, exit the download
  268.             WaitNextEvent( keyDownMask, &e, 0, NULL );
  269.             
  270.             if (e.what == keyDown && e.modifiers & cmdKey) {
  271.                 if ( (e.message & charCodeMask) == '.' )
  272.                     break;
  273.             }
  274.             
  275.         } while ( count > 0 );
  276.     
  277.         DisposeDialog(gStatusDlg);
  278.         if ( err == noErr && fsendblk.ioResult != noErr )
  279.             err = fsendblk.ioResult;
  280.         fclose( fin );
  281.     }
  282.     
  283.     return err;
  284. }
  285.  
  286. OSErr
  287. sendusb( char *printer_name, char *sourcefile, long blocksize, int repeat_count )
  288. {
  289.     OSStatus err = noErr;
  290.     outbuffer = (char *) malloc( blocksize );
  291.     memset( &fsendblk, 0, sizeof(fsendblk) );
  292.     
  293.     if ( !outbuffer )
  294.         err = iMemFullErr;    // memfull error
  295.     if ( err == noErr )
  296.         err = OpenClassDriver( printer_name );
  297.     if ( err == noErr )
  298.     {
  299.         for ( ; err == noErr && repeat_count > 0; --repeat_count )
  300.             err = sendfile( sourcefile, blocksize );
  301.  
  302.         if ( err != noErr )
  303.             KillIO( fsendblk.ioRefNum );
  304.             
  305.         if ( fsendblk.ioRefNum != -1 )
  306.             CloseDriver(fsendblk.ioRefNum);
  307.     }
  308.     if ( outbuffer )
  309.         free( outbuffer );
  310.     
  311.     if ( err != noErr )
  312.     {
  313.         unsigned char *p;
  314.         int                slen;
  315.         switch ( err )
  316.         {    
  317.             case  iMemFullErr:                         p = "\p" PROGRAM "Not enough memory. (Increase App heap, or use smaller block)"; break;
  318.             case    kUSBInternalErr:                    p = "\p" kStrPrinterClass "Internal error"; break;
  319.             case    kUSBUnknownDeviceErr:            p = "\p" kStrPrinterClass "Unknown device"; break;
  320.             case    kUSBUnknownPipeErr:                 p = "\p" kStrPrinterClass "Unknown pipe"; break;
  321.             case    kUSBTooManyPipesErr:                p = "\p" kStrPrinterClass "Too many pipes"; break;
  322.             case    kUSBIncorrectTypeErr:            p = "\p" kStrPrinterClass "Incorrect type"; break;
  323.             case    kUSBRqErr:                            p = "\p" kStrPrinterClass "Request error"; break;
  324.             case    kUSBUnknownRequestErr:            p = "\p" kStrPrinterClass "Unknown request"; break;
  325.             case    kUSBTooManyTransactionsErr:    p = "\p" kStrPrinterClass "Too many transactions"; break;
  326.             case    kUSBAlreadyOpenErr:                p = "\p" kStrPrinterClass "Already open"; break;
  327.             case    kUSBNoDeviceErr:                    p = "\p" kStrPrinterClass "No device"; break;
  328.             case    kUSBDeviceErr:                        p = "\p" kStrPrinterClass "Device error"; break;
  329.             case    kUSBOutOfMemoryErr:                p = "\p" kStrPrinterClass "Out of memory"; break;
  330.             case    kUSBNotFound:                        p = "\p" kStrPrinterClass "Not found"; break;
  331.             case    kUSBLinkErr:                        p = "\p" kStrPrinterClass "Link Err"; break;
  332.             case    kUSBCRCErr:                            p = "\p" kStrPrinterClass "Comms/Device err, bad CRC";  break;        
  333.             case    kUSBBitstufErr:                    p = "\p" kStrPrinterClass "Comms/Device err, bitstuffing"; break;        
  334.             case    kUSBDataToggleErr:                p = "\p" kStrPrinterClass "Comms/Device err, Bad data toggle"; break;        
  335.             case    kUSBEndpointStallErr:            p = "\p" kStrPrinterClass "Device didn't understand"; break;        
  336.             case    kUSBNotRespondingErr:            p = "\p" kStrPrinterClass "No device, device hung"; break;        
  337.             case    kUSBPIDCheckErr:                    p = "\p" kStrPrinterClass "Comms/Device err, PID CRC error"; break;        
  338.             case    kUSBWrongPIDErr:                    p = "\p" kStrPrinterClass "Comms/Device err, Bad or wrong PID"; break;        
  339.             case    kUSBOverRunErr:                    p = "\p" kStrPrinterClass "Packet too large or more data than buffer"; break;        
  340.             case    kUSBUnderRunErr:                    p = "\p" kStrPrinterClass "Less data than buffer"; break;        
  341.             case    kUSBRes1Err:                        p = "\p" kStrPrinterClass "kUSBRes1Err"; break;        
  342.             case    kUSBRes2Err:                        p = "\p" kStrPrinterClass "kUSBRes1Err"; break;        
  343.             case    kUSBBufOvrRunErr:                    p = "\p" kStrPrinterClass "Buffer over run error"; break;        
  344.             case    kUSBBufUnderRunErr:                p = "\p" kStrPrinterClass "Buffer under run error"; break;        
  345.             case    kUSBNotSent1Err:                    p = "\p" kStrPrinterClass "Transaction not sent1"; break;        
  346.             case    kUSBNotSent2Err:                    p = "\p" kStrPrinterClass "Transaction not sent2"; break;    
  347.             default:
  348.                 p = "\p" kStrPrinterClass "Unknown error nnnnnnnn";
  349.                 NumToString( err, p + *p - 8 );
  350.                 slen = *(p + *p - 8);
  351.                 *(p + *p - 8) = ' ';
  352.                 *p += slen - 8;
  353.                 break;
  354.         }
  355.         
  356.         ParamText( p, nil, nil, nil );
  357.         StopAlert( 768, nil );
  358.         err = noErr;
  359.     }
  360.     return err;
  361. }
  362.  
  363. /* eof */
  364.